/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.tactics;

import robocup.component.ControllerNumbers;
import robocup.component.actionfactories.BasicActionFactory;
import robocup.component.actionfactories.TurnNeckActionFactory;

/**
 * The state for intercepting an opponent with ball. This state is triggered 
 * when the player can not kick the ball and is the one of the fastest player to 
 * the opponent with ball.
 * 
 *  TODO: The logic used here is pretty stupid and only used to get the 
 *  Source-Code release running. Add your opponent interception logic here
 *  or create a seperate situation.
 */
public class InterceptOpponentState extends AbstractState {

	/**
	 * Simple state that defines ball-interception.
	 * 
	 * @param parent -
	 *            the StateEvaluation (parent) object
	 */
	public InterceptOpponentState(StateEvaluation parent) {

		super(parent);
		this.state = STATES.INTERCEPT_OPPONENT;
	}

	/**
   * Never go when fastest to ball as this is handled by the 
   * {@link InterceptBallState}.
	 * Always go when fastest teammate to intercept the opponent.
   * 
   * (This is a very simple version. Add your logic here!)
	 */
	@Override
	public boolean preCondition() {

		if (!this.checkPlayMode() 
        || !this.getBall().isReliable()
				|| this.getPlayer().canKick(getWorld().getBallRef())
        || (this.getProphet().getFastestTeammateToBall() !=null &&
            this.getProphet().getFastestTeammateToBall().isMe())) {
			return false;
		}

    //closest to ball or near to ball
		return this.getWorld().getClosestPlayerTo(this.getWorld().getTeammates(), 
        this.getWorld().getBallRef().getPosition(), true).isMe()
		  || this.getWorld().getBallRef().getDistance(this.getWorld().getSelfRef()) < 5;
  }

	/**
	 * Probability is always 1.
	 */
	@Override
	protected double successProbability() {

		return 1;
	}

	/**
	 * Benefit is always 0.95.
	 */
	@Override
	protected double successBenefit() {

		return 0.95;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see robocup.component.tactics.AbstractState#calculateMainAction()
	 */
	public void calculateMainAction() {

			mainAction = BasicActionFactory.moveToPos(getWorld(), getWorld()
					.getBallRef().getPosition(), ControllerNumbers.STAMINA_LEVEL.MEDIUM);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see robocup.component.tactics.AbstractState#calculateTurnNeckAction()
	 */
    @Override
	public void calculateTurnNeckAction() {
    
    //ball old -> watch ball
		if (this.getWorld().getBallRef().getAge(this.getWorld().getBodyCycle(),
						robocup.component.worldobjects.Ball.UPDATE_MODE.SEEN_WITHOUT_SPEED) > 2) {
			turnNeckAction = TurnNeckActionFactory.getAction(this.getWorld(),
					state, mainAction, viewModeAction, this
							.getWorld().getBallRef());
			return;
		}

		super.calculateTurnNeckAction();
	}

}
